﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Markup;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Dimok.FilteredView {
  [ContentProperty("Value")]
  public class FilterDescription : Dimok.Model {
    // Fields
    private string filterValue = "";
    private string member;
    // Events
		public event PropertyChangedEventHandler PropertyChanged;
    // Methods
    public FilterDescription()
      : this(string.Empty,null) {
    }

    [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public FilterDescription(string member, string filterValue) {
      this.member = member;
      this.filterValue = filterValue;
    }
    public void Mirror(FilterDescription fd) {
      member = fd.Member;
      filterValue = fd.Value;
    }

    // Properties
    public string Member {
      get {        return this.member;      }
      set {
        if (this.member != value) {
          this.member = value;
          this.RaisePropertyChanged("Member");
        }
      }
    }

    public string Value {
      get {        return this.filterValue;      }
      set {
        if (this.filterValue != value) {
          this.filterValue = value;
          this.RaisePropertyChanged("Value");
					if (PropertyChanged != null)
						PropertyChanged(this, new PropertyChangedEventArgs("Value"));
        }
      }
    }
		public override string ToString() { return "[" + Member + "]:" + Value; }
  }

	public static class Extentions {
		static public IEnumerable<FilterDescription> Filters(this IEnumerable<FilterDescription> c) {
			return c.Where(fd => fd.Value + "" != "");
		}
		public static string ToString(this IEnumerable<FilterDescription> c ) {
			return string.Join(",", c.Select(fd => fd.ToString()).ToArray());
		}
	}

  public class FilterDescriptionCollection : ObservableCollection<FilterDescription> {
		public void ClearFilters() {
			foreach (var fd in this)
				fd.Value = "";
		}
    private new void Add(FilterDescription item){
			base.Add(item);
		}
		void value_PropertyChanged(object sender, PropertyChangedEventArgs e) {
			OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace,sender,sender,-1));
		}
		public FilterDescription Add(string filterName) {
			string filterValue = null;
			return Add(filterName, filterValue);
		}
    public FilterDescription Add(string filterName, string filterValue) {
			var filterDescription = this.FirstOrDefault(fd => fd.Member == filterName);
			if (filterDescription == null) {
				filterDescription = new FilterDescription(filterName, filterValue+"");
				(filterDescription).PropertyChanged += new PropertyChangedEventHandler(value_PropertyChanged);
				Add(filterDescription);
			} else {
				if (filterValue != null) {
					filterDescription.Value = filterValue;
					OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
				}
			}
			return filterDescription;
		}
		public bool HasFilter(string filterName) { return this.Any(fd => fd.Member == filterName); }
		public override string ToString() {
			return string.Join(",", this.Filters().Select(fd => fd.ToString()).ToArray());
		}
    public event PropertyChangedEventHandler FilterChanged {
      add {
        this.PropertyChanged += value;
      }
      remove {
        this.PropertyChanged -= value;
      }
    }
  }


  public enum FilterOperator {
    NoFilter = 0,
    IsEmpty,
    IsNotEmpty,
    IsNull,
    IsNotNull,
    IsLessThan,
    IsLessThanOrEqualTo,
    IsEqualTo,
    IsNotEqualTo,
    IsGreaterThanOrEqualTo,
    IsGreaterThan,
    StartsWith,
    EndsWith,
    Contains,
    DoesNotContain,
    IsContainedIn,
    IsBetween,
    IsNotBetween
  }
}
